// 负责发送请求的类。负责发送请求、接收响应、判断权限、头设置、文件下载等。

// 引入axios
import axios from 'axios'
import {Message, MessageBox} from 'element-ui'
import store from '../store'

// 基本信息定义部分。
// 1. 请求baseURL ，后面请求时会在前面加上这个地址，拼接成完整的url
const baseURL = 'http://localhost/api'
// 2. token设置到http请求头的key。
const token_head_key = 'Token'
// 3. 文件下载时filename放在相应头的key名。
const filename_head_key = 'filename'

// 创建并定义
const service = axios.create({
    baseURL,
    timeout: 5000 // 超时时间，5秒
})

// request 拦截器
service.interceptors.request.use(
    config => {
        // 发送请求前，判断store里是否有token，有token的话添加到请求头里。具体请求头的命名，与后端保持一样的规则。
        const token = store.getters.token
        if (token) {
            config.headers[token_head_key] = token
        }
        return config
    },
    error => {
        console.log(error)
        return Promise.reject(error)
    }
)

// response 相应拦截器。当不是正常返回时，弹出了错误信息。所以预期情况下，后台应该返回code===0
service.interceptors.response.use(
    response => {
        // response.data 才是实际服务器返回的json数据。请根据实际项目返回约定的规则进行相应的修改。
        // 此项目中使用的后台返回的数据格式为：{code, msg, data}
        const res = response.data
        if (res.code === 0) {
            // 状态码为0 成功，直接返回最重要的响应信息数据，code和msg就不用返回了。
            return res.data
        }

        // 如果是下载文件。
        if (response.config.responseType === 'blob' || response.config.responseType === 'arraybuffer') {
            let blob = new Blob([res],{type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'});
            let downloadElement = document.createElement('a');
            let href = window.URL.createObjectURL(blob);
            downloadElement.href = href;
            // 从相应头中获取文件名称，此处使用的自定义文件头的文件名，注意与后端的匹配。
            let filename = response.headers[filename];
            downloadElement.download = decodeURI(filename);
            document.body.appendChild(downloadElement);
            downloadElement.click();
            document.body.removeChild(downloadElement);
            window.URL.revokeObjectURL(href);
            return
        }

        // 弹出一个消息框，提示错误信息。
        Message({
            message: res.data || 'Error',
            type: 'error',
            duration: 5000
        })

        // 另外，如果code === -2 表示token过期，需要跳转到登录页。
        if (res.code === -2) {
            // 调用store 的user模块中的 resetToken action
            store.dispatch('user/resetToken')
            .then(()=>{
                location.reload()
            })
        }

        // 其他的情况，返回错误。
        return Promise.reject(new Error(res.data || 'Error'))
    },
    error => {
        Message({
            message: error.message,
            type: 'error',
            duration: 5000
        })
        return Promise.reject(error)
    }
)

export default service